package leetcode.p65;

/**
 * @author: trtan
 * @date: 2021-06-17 08:49
 **/
public class ValidNumber {
    /**
     * 大模拟，简直了
     * @param s
     * @return boolean
     * @author trtan
     * @date 2021/6/17 8:51
     */
    public boolean isNumber(String s) {
        // 判断是否包含除合法字符的其它字符
        if (s.length() == 0 || haveOtherChar(s)) {
            return false;
        }
        // 判断是整数还是小数
        boolean isDecimal = s.contains(".");
        int i = 0;
        // 判断首部是否包含正负数符号字符
        if (s.charAt(0) == '+' || s.charAt(0) == '-') {
            i++;
        }
        //如果是小数
        if (isDecimal) {
            char pre = s.charAt(0);
            boolean haveE = false;
            boolean havePoint = false;
            boolean haveNumber = false;
            boolean backEHaveNumber = true;
            while (i < s.length()) {
                char ch = s.charAt(i);
                // 如果当前是.
                if (ch == '.') {
                    // 如果存在多个点
                    if (havePoint) {
                        return false;
                    }
                    havePoint = true;
                } else if (ch == 'E' || ch == 'e') {
                    // 如果当前是E 那么E后面一定要有数字， 将E后面有数字标识为false
                    backEHaveNumber = false;
                    // 判断是否存在多个E
                    if (haveE) {
                        return false;
                    }
                    // 小数E必须在小数点后出现
                    if (!havePoint) {
                        return false;
                    }
                    // E的前面必须也要有数字
                    if (!haveNumber) {
                        return false;
                    }
                    haveE = true;
                } else if (ch == '+' || ch == '-') {
                    // 如果当前是+-字符 由于中间出现这种符号只能跟在e后面
                    if (pre != 'e' && pre != 'E') {
                        return false;
                    }
                } else {
                    // 存在数字
                    haveNumber = true;
                    // E后面是否有数字
                    if (haveE) {
                        backEHaveNumber = true;
                    }
                }
                i++;
                pre = ch;
            }
            // 如果最后没有数字或者E后面没有数字那么答案不合法
            if (!haveNumber || !backEHaveNumber) {
                return false;
            }
        } else {
            // 对整数的情况判断
            char pre = s.charAt(0);
            boolean haveE = false;
            boolean haveNumber = false;
            boolean backEHaveNumber = true;
            while (i < s.length()) {
                char ch = s.charAt(i);
                // 如果当前是e
                if (ch == 'E' || ch == 'e') {
                    //E后面一定要有数字 首先将标识为false
                    backEHaveNumber = false;
                    // 判断e是否出现多次
                    if (haveE) {
                        return false;
                    }
                    //判断e前是否有数字
                    if (!haveNumber) {
                        return false;
                    }
                    haveE = true;
                } else if (ch == '+' || ch == '-') {
                    // 如果中间出现+-符号，那么只能跟在e后面
                    if (pre != 'e' && pre != 'E') {
                        return false;
                    }
                } else {
                    //标识有数字出现
                    haveNumber = true;
                    //e后面有数字出现
                    if (haveE) {
                        backEHaveNumber = true;
                    }
                }
                pre = ch;
                i++;
            }
            // 如果存在数字并且有e时e后面有数字
            if (!haveNumber || !backEHaveNumber) {
                return false;
            }
        }
        return true;
    }

    boolean haveOtherChar(String s) {
        for (int i = 0; i < s.length(); i++) {
            char ch = s.charAt(i);
            if (ch != '.' && ch != 'e' && ch != 'E' && ch != '+' && ch != '-' && (ch < '0' || ch > '9')) {
                return true;
            }
        }
        return false;
    }
}
